package net.lqy.aipan.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import net.lqy.aipan.component.StorageEngine;
import net.lqy.aipan.config.AccountConfig;
import net.lqy.aipan.config.MinioConfig;
import net.lqy.aipan.dto.AccountDTO;
import net.lqy.aipan.dto.StorageDTO;
import net.lqy.aipan.enums.AccountRoleEnum;
import net.lqy.aipan.enums.BizCodeEnum;
import net.lqy.aipan.exception.BizException;
import net.lqy.aipan.mapper.AccountFileMapper;
import net.lqy.aipan.mapper.AccountMapper;
import net.lqy.aipan.mapper.StorageMapper;
import net.lqy.aipan.model.AccountDO;
import net.lqy.aipan.model.AccountFileDO;
import net.lqy.aipan.model.StorageDO;
import net.lqy.aipan.request.AccountLoginReq;
import net.lqy.aipan.request.AccountRegisterReq;
import net.lqy.aipan.request.FolderCreateReq;
import net.lqy.aipan.service.AccountFileService;
import net.lqy.aipan.service.AccountService;
import net.lqy.aipan.service.StorageService;
import net.lqy.aipan.util.CommonUtil;
import net.lqy.aipan.util.JsonData;
import net.lqy.aipan.util.SpringBeanUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;
import org.springframework.web.multipart.MultipartFile;

import java.nio.charset.StandardCharsets;

/**
 * @title: AccountServiceImpl
 * @Author lqy
 * @Date: 2025-06-02 11:54
 * @Version 1.0
 */
@Service
@Slf4j
public class AccountServiceImpl implements AccountService {
    @Autowired
    private AccountMapper accountMapper;
    @Autowired
    private StorageEngine storageEngine;
    @Autowired
    private MinioConfig minioConfig;
    @Autowired
    private StorageService storageService;
    @Autowired
    private AccountFileService accountFileService;
    @Autowired
    private AccountFileMapper accountFileMapper;


    @Override
    @SneakyThrows
    @Transactional(rollbackFor = Exception.class)
    public JsonData register(AccountRegisterReq request) {
        //查询手机号是否重复
        AccountDO selected = accountMapper.selectOne(new QueryWrapper<AccountDO>().eq("phone", request.getPhone()));
        if (selected != null) {
            return JsonData.buildResult(BizCodeEnum.ACCOUNT_REPEAT);
        }
        //加密密码
        String digest = encryptPassword(request.getPassword());
        AccountDO accountDO = SpringBeanUtil.copyProperties(request, AccountDO.class);
        accountDO.setPassword(digest);

        accountDO.setRole(AccountRoleEnum.COMMON.name());
        //插入数据库
        accountMapper.insert(accountDO);

        //创建默认存储空间
        storageService.initStorage(accountDO.getId());

        //初始化根目录
        FolderCreateReq folderCreateReq = FolderCreateReq.builder().accountId(accountDO.getId()).folderName(AccountConfig.ROOT_FOLDER_NAME).parentId(AccountConfig.ROOT_PARENT_ID).build();
        accountFileService.createFolder(folderCreateReq);

        return JsonData.buildSuccess();
    }

    @Override
    public String uploadAvatar(MultipartFile file) {
        String objectKey = CommonUtil.getFilePath(file.getOriginalFilename());
        storageEngine.upload(minioConfig.getAvatarBucketName(), objectKey, file);
        return minioConfig.getEndpoint() + "/" + minioConfig.getAvatarBucketName() + "/" + objectKey;
    }

    @Override
    public AccountDTO login(AccountLoginReq request) {
        AccountDO accountDO = accountMapper.selectOne(new QueryWrapper<AccountDO>().eq("phone", request.getPhone()));
        if (accountDO == null) {
            throw new BizException(BizCodeEnum.ACCOUNT_UNREGISTER);
        } else {
            if (encryptPassword(request.getPassword()).equals(accountDO.getPassword())) {
                AccountDTO accountDTO = SpringBeanUtil.copyProperties(accountDO, AccountDTO.class);
                return accountDTO;
            } else {
                throw new BizException(BizCodeEnum.ACCOUNT_PWD_ERROR);
            }
        }

    }

    @Override
    public AccountDTO detail(Long id) {

        AccountDO accountDO = accountMapper.selectById(id);
        AccountDTO accountDTO = SpringBeanUtil.copyProperties(accountDO, AccountDTO.class);

        StorageDO storageDO=storageService.selectByAccountId(accountDO.getId());

        accountDTO.setStorageDTO(SpringBeanUtil.copyProperties(storageDO, StorageDTO.class));

        AccountFileDO accountFileDO = accountFileMapper.selectOne(new QueryWrapper<AccountFileDO>().eq("account_id", id).eq("parent_id", AccountConfig.ROOT_PARENT_ID));
        accountDTO.setRootFileId(accountFileDO.getId());
        accountDTO.setRootFileName(accountFileDO.getFileName());
        return accountDTO;
    }

    /**
     * 对原始密码进行 MD5 加密，加盐处理
     *
     * @param rawPassword 原始密码
     * @return 加密后的密码字符串
     */
    private String encryptPassword(String rawPassword) {
        return DigestUtils.md5DigestAsHex((rawPassword + AccountConfig.ACCOUNT_SALT).getBytes(StandardCharsets.UTF_8));
    }

}
